﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "toptable.h"
#include "lefttable.h"
#include "parseprotocol.h"
#include "asduparse.h"
#include  "rightdisplay.h"
#include<QDomDocument>
#include <QMessageBox>
#include <QStandardItemModel>
#include <QFileDialog>
#include <QString>
#include <QDebug>


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{

    ui->setupUi(this);

    _ptopTable=new topTable();//->初始化顶栏
    _leftTable=new leftTable();//->初始化右栏
    _rightTable();//->右侧显示完成
    _parseProtocol=new parseProtocol();//->解析104
    _ASDUparse=new ASDUparse();//->解析ASDU
    _rightDisplay=new rightDisplay();//->解析右边

    pInitbrieftable();
    pInitleftTable();
    QString haha=pParseQDS(170);

}

MainWindow::~MainWindow()
{
    delete ui;
}


//********************************************************************************
//函数名：void pInitbrieftable()
//功能：初始化顶层元素，初始化顶层数据源，连接顶层信号和槽，加载数据源

void MainWindow::pInitbrieftable()
{
    // 设置7段列标：1方向，2序号，3方向，4简析，5描述，6时间，7源码
     connect(ui->action,SIGNAL(triggered()),this,SLOT(popenFile()));
    ui->treeView->setModel(_ptopTable->model);
}


//********************************************************************************
//函数名：void pInitleftTable()
//功能：初始化左侧元素，初始化左侧数据源，连接顶层信号和槽，加载数据源
void MainWindow::pInitleftTable()
{
    ui->treeView_2->setModel(_leftTable->model);
}


//********************************************************************************
//函数名：void pInformation()
//功能：   在textedit按位输出信息位置
void MainWindow::pInformation(const QString data_parse)
{

    switch (_ASDUparse->getType()) {
    case 1:
        QString tmp=_rightDisplay->diaplayM_SP_NA_1(data_parse,_ASDUparse->getSq(),_ASDUparse->getVsq());
        ui->textEdit->append(tmp);
        break;
    }
//    //向当前光标插入
//    ui->textEdit->textCursor().insertText("00 老公爱你");
//    //末尾追加
//    ui->textEdit->append("111");
//    ui->textEdit->append("111");


//    QString tmp;//临时数据——用来装在信息字库返回值
//    int tmp2=INFORMATIONADDRESS+6;//信息字开始地址


//    if(_ASDUparse->getSq()==0)
//    {

//    }else
//    {
//        switch (p_type) {
//        case 1:

//            //信息对象首地址:3个八位组——前低后高
//            tmp=data_parse.mid(INFORMATIONADDRESS+4,2)+data_parse.mid(INFORMATIONADDRESS+2,2)+data_parse.mid(INFORMATIONADDRESS,2);
//            int info=tmp.toInt(&ok,16);
//            ui->textEdit->append(tr("%1——信息字首地址：%2")
//                                 .arg(data_parse.mid(INFORMATIONADDRESS,6))
//                                 .arg(info));

//            //带品质描述词的单点信息(IEV 371-02-07)(SIQ)

//            for(int heihei=0;heihei<p_num;heihei++)
//            {
//                tmp=pParseSIQ(tmp2);
//                 ui->textEdit->append(tr("数据%1").arg(heihei+1));
//                ui->textEdit->append(tmp);
//                tmp2+=2;
//            }
//            break;
//        }
//    }
}
//********************************************************************************
//函数名：void _rightTable()
//功能：   在右侧显示展示信息字
void MainWindow::_rightTable()
{
    for(int i=0;i<=100;i++)
    {
        ui->textEdit->append("111");
        ui->textEdit->append("111");
    }
}




//********************************************************************************
//函数名：open_file
//功能：槽函数——打开xml文件
void MainWindow::popenFile()
{
    QString fileName =
            QFileDialog::getOpenFileName(this, tr("打开解析文件"),
                                         QDir::currentPath(),
                                         tr("XBEL Files (*.xbel *.log *.xml)"));

            if(fileName.isEmpty())
                return;

            QFile file(fileName);
            if(!file.open(QFile::ReadOnly|QFile::Text))
            {
                QMessageBox::warning(this, tr("SAX Bookmarks"),
                                     tr("Cannot read file %1:\n%2.")
                                     .arg(fileName)
                                     .arg(file.errorString()));
                return;
            }
           _ptopTable->read(&file);
}
//********************************************************************************
//函数名：on_treeView_clicked
//功能：从上面取数据

void MainWindow::on_treeView_clicked(const QModelIndex &index)
{
    //清空数据源

   // modelLeft->clear();


    //->左栏的更新
    _leftTable->model->clear();//->清空数据模型




    ui->textEdit->clear();
//    //获取帧数据
    QString str;
    if(index.column()==4)
        str+=index.data().toString();
    else
        str+=index.sibling(index.row(),4).data().toString();

    qDebug()<<str;
    //处理字符——去掉所有空格
    str.remove(QChar(' '));
    qDebug()<<str;


    _parseProtocol->setItemData(str);//解析104

    _leftTable->createRootNode();//->根节点
    _leftTable->createFirstNode(_parseProtocol->get68());//->首节点
    _leftTable->createLengthNode(_parseProtocol->getLength());//长度节点

    _leftTable->createControlNode(_parseProtocol->getControl1());//->控制节点根节点
    _leftTable->createControlNode1(_parseProtocol->getControl11());//->控制节点1
    _leftTable->createControlNode2(_parseProtocol->getControl12());//->控制节点2
    _leftTable->createControlNode3(_parseProtocol->getControl13());//->控制节点3
    _leftTable->createControlNode4(_parseProtocol->getControl14());//->控制节点4
    if(_parseProtocol->getIC(str)==1)
    {
        _leftTable->createTypeNode(_ASDUparse->strAsduTypeName(str));//->类型节点
        _leftTable->createCanChange(_ASDUparse->strGetCanChange(str));//->可变结构限定词
        _leftTable->createTransferreason(_ASDUparse->strGetReasonName(str));//->传输原因
        _leftTable->createAddress(_ASDUparse->strGetAddress(str));//->公共地址
    }


////    updateLeftTable(str);
    pInformation(str);
    ui->treeView_2->expandAll();
}


//********************************************************************************
//函数名：pParseSIQ
//功能：解析带品质描述词的单点信息(IEV 371-02-07)(SIQ)
QString MainWindow::pParseSIQ(int data_parse)
{

//        SIQ                    ：=CP8{SPI，RES，BL，SB，NT，IV}
//        SPI=单点信息    ：=BS1[1]<0..1>
//                      <0>      ：=开
//                      <1>      ：=合
//        RES=RESERVE          ：=BS3[2..4]<0>
//        BL                     ：=BS1[5]<0..1>
//                      <0>      ：=未被闭锁
//                       <1>      ：=被闭锁
//        SB                     ：=BS1[6]<0..1>
//                      <0>      ：=未被取代
//                      <1>      ：=被取代
//        NT                     ：=BS1[7]<0..1>
//                      <0>      ：=当前值
//                      <1>       ：=非当前值
//        IV                      ：=BS1[8]<0..1>
//                     <0>        ：=有效
//                     <1>        ：=无效

    int l_i_IV=(data_parse>>7)%2;
    QString l_s_IV;

    if(l_i_IV==0)
        l_s_IV="IV =0  有效 ";
    else
        l_s_IV="IV =1  无效 ";

    //        NT                     ：=BS1[7]<0..1>
    //                      <0>      ：=当前值
    //                      <1>       ：=非当前值
    int l_i_NT=(data_parse>>6)%2;
    QString l_s_NT;

    if(l_i_NT==0)
        l_s_NT="NT=0 当前值 ";
    else
        l_s_NT="NT=1 非当前值 ";

    //        SB                     ：=BS1[6]<0..1>
    //                      <0>      ：=未被取代
    //                      <1>      ：=被取代

    int l_i_SB=(data_parse>>5)%2;
    QString l_s_SB;

    if(l_i_SB==0)
        l_s_SB="SB=0 未被取代 ";
    else
        l_s_SB="SB=1 被取代 ";

    //        BL                     ：=BS1[5]<0..1>
    //                      <0>      ：=未被闭锁
    //                       <1>      ：=被闭锁

    int l_i_BL=(data_parse>>4)%2;
    QString l_s_BL;

    if(l_i_BL==0)
        l_s_BL="SB=0 被闭锁  ";
    else
        l_s_BL="SB=1 未被闭锁  ";

    //        SPI=单点信息    ：=BS1[1]<0..1>
    //                      <0>      ：=开
    //                      <1>      ：=合

    int l_i_SPI=data_parse%2;
    QString l_s_SPI;

    if(l_i_SPI==0)
        l_s_SPI="SPI=0 开  ";
    else
        l_s_SPI="SPI=1 合  ";

    QString l_all="SIQ=CP8{SPI，RES，BL，SB，NT，IV}"+l_s_SPI+l_s_BL+l_s_SB+l_s_NT+l_s_IV;
    qDebug()<<l_all;
    return l_all;
}

//********************************************************************************
//函数名：pParseSIQ
//功能：解析带品质描述词的单点信息(IEV 371-02-07)(SIQ)

QString MainWindow::pParseDIQ(int data_parse)
{
//    DIQ                    ：=CP8{DPI，RES，BL，SB，NT，IV}
//        DPI=双点信息           ：=UI2[1..2]<0..3>                           (Type 1.1)
//                    <0>        ：=不确定或中间状态
//                    <1>        ：=确定状态开
//                    <2>        ：=确定状态合
//                    <3>        ：=不确定或中间状态
//        RES=RESERVE         ：=BS2[3..4]<0>                              (Type 6)
//        BL                     ：=BS1[5]<0..1>                              (Type 6)
//                      <0>        ：=未被闭锁
//                      <1>        ：=被闭锁
//        SB                     ：=BS1[6]<0..1>                              (Type 6)
//                    <0>        ：=未被取代
//                    <1>        ：=被取代
//        NT                     ：=BS1[7]<0..1>                               (Type 6)
//                    <0>        ：=当前值
//                    <1>        ：=非当前值
//        IV                      ：=BS1[8]<0..1>                               (Type 6)
//                    <0>         ：=有效
//                    <1>         ：=无效

    int l_i_IV=(data_parse>>7)%2;
    QString l_s_IV;

    if(l_i_IV==0)
        l_s_IV="IV =0  有效 ";
    else
        l_s_IV="IV =1  无效 ";

    //        NT                     ：=BS1[7]<0..1>
    //                      <0>      ：=当前值
    //                      <1>       ：=非当前值
    int l_i_NT=(data_parse>>6)%2;
    QString l_s_NT;

    if(l_i_NT==0)
        l_s_NT="NT=0 当前值 ";
    else
        l_s_NT="NT=1 非当前值 ";

    //        SB                     ：=BS1[6]<0..1>
    //                      <0>      ：=未被取代
    //                      <1>      ：=被取代

    int l_i_SB=(data_parse>>5)%2;
    QString l_s_SB;

    if(l_i_SB==0)
        l_s_SB="SB=0 未被取代 ";
    else
        l_s_SB="SB=1 被取代 ";

    //        BL                     ：=BS1[5]<0..1>
    //                      <0>      ：=未被闭锁
    //                       <1>      ：=被闭锁

    int l_i_BL=(data_parse>>4)%2;
    QString l_s_BL;

    if(l_i_BL==0)
        l_s_BL="SB=0 未被闭锁  ";
    else
        l_s_BL="SB=1 被闭锁  ";

    //        DPI=双点信息           ：=UI2[1..2]<0..3>                           (Type 1.1)
    //                    <0>        ：=不确定或中间状态
    //                    <1>        ：=确定状态开
    //                    <2>        ：=确定状态合
    //                    <3>        ：=不确定或中间状态

    int l_i_DPI=((data_parse>>1)%2)*2+data_parse%2;
    QString l_s_DPI;

    switch (l_i_DPI) {
    case 0:
        l_s_DPI="DPI=0 不确定或中间状态 ";
        break;
    case 1:
        l_s_DPI="DPI=1 确定状态开 ";
        break;
    case 2:
        l_s_DPI="DPI=2 确定状态合 ";
        break;
    default:
         l_s_DPI="DPI=3 不确定或中间状态 ";
        break;
    }
    QString l_all="DIQ=CP8{DPI，RES，BL，SB，NT，IV}"+l_s_DPI+l_s_BL+l_s_SB+l_s_NT+l_s_IV;
    qDebug()<<l_all;
    return l_all;
}

//********************************************************************************
//函数名：pParseQDS
//功能：解析带品质描述词的单点信息(IEV 371-02-07)(SIQ)

QString MainWindow::pParseQDS(int data_parse)
{
//    QDS              ：=CP8{OV，RES，BL，SB，NT，IV}
//        OV               ：=BS1[1] <0..1>                                     (Type 6)
//                  <0>     ：=未溢出
//                  <1>     ：=溢出
//        RES=RESERVE     ：=BS3[2..4]<0>                                     (Type 6)
//        BL                ：=BS1[5]<0..1>                                     (Type 6)
//                  <0>     ：=未被闭锁
//                  <1>      ：=被闭锁
//        SB                ：=BS1[6]<0..1>                                      (Type 6)
//                  <0>      ：=未被取代
//                  <1>      ：=被取代
//        NT                 ：=BS1[7]<0..1>                                     (Type 6)
//                  <0>       ：=当前值
//                  <1>       ：=非当前值
//        IV                  ：=BS1[8]<0..1>                                     (Type 6)
//                 <0>        ：=有效
//                 <1>        ：=无效




    int l_i_IV=(data_parse>>7)%2;
    QString l_s_IV;

    if(l_i_IV==0)
        l_s_IV="IV =0  有效 ";
    else
        l_s_IV="IV =1  无效 ";

    //        NT                     ：=BS1[7]<0..1>
    //                      <0>      ：=当前值
    //                      <1>       ：=非当前值
    int l_i_NT=(data_parse>>6)%2;
    QString l_s_NT;

    if(l_i_NT==0)
        l_s_NT="NT=0 当前值 ";
    else
        l_s_NT="NT=1 非当前值 ";

    //        SB                     ：=BS1[6]<0..1>
    //                      <0>      ：=未被取代
    //                      <1>      ：=被取代

    int l_i_SB=(data_parse>>5)%2;
    QString l_s_SB;

    if(l_i_SB==0)
        l_s_SB="SB=0 未被取代 ";
    else
        l_s_SB="SB=1 被取代 ";

    //        BL                     ：=BS1[5]<0..1>
    //                      <0>      ：=未被闭锁
    //                       <1>      ：=被闭锁

    int l_i_BL=(data_parse>>4)%2;
    QString l_s_BL;

    if(l_i_BL==0)
        l_s_BL="SB=0 未被闭锁  ";
    else
        l_s_BL="SB=1 被闭锁  ";

//    OV               ：=BS1[1] <0..1>                                     (Type 6)
//                  <0>     ：=未溢出
//                  <1>     ：=溢出


    int l_i_OV=data_parse%2;
    QString l_s_OV;

    if(l_i_OV==0)
        l_s_OV="OV=0 未溢出  ";
    else
        l_s_OV="OV=1 溢出  ";



    QString l_all="QDS=CP8{OV，RES，BL，SB，NT，IV}"+l_s_OV+l_s_BL+l_s_SB+l_s_NT+l_s_IV;
    qDebug()<<l_all;
    return l_all;
}

//********************************************************************************
//函数名：pParseQDP
//功能：继电保护设备事件的品质描述词(单个的八位位组 QDP)

QString MainWindow::pParseQDP(int data_parse)
{

//    QDP                    ：=CP8{RES,EI,BL,SB,NT,IV}
//       RES=RESERVE          ：=BS3[1..3]<0>                              (Type 6)
//       EI                      ：=BS1[4]<0..1>                              (Type 6)
//                      <0>       ：=动作时间有效
//                      <1>       ：=动作时间无效
//       BL                      ：=BS1[5]<0..1>                              (Type 6)
//                      <0>       ：=未被闭锁
//                      <1>       ：=被闭锁
//       SB                      ：=BS1[6]<0..1>                             (TYPE 6)
//                     <0>       ：=未被取代
//                     <1>       ：=被取代
//       NT                      ：=BS1[7]<0..1>                             (Type 6)
//                     <0>       ：=当前值
//                      <1>       ：=非当前值
//       IV                      ：=BS1[8]<0..1>                              (Type 6)
//                     <0>       ：=有效
//                     <1>       ：=无效

    int l_i_IV=(data_parse>>7)%2;
    QString l_s_IV;

    if(l_i_IV==0)
        l_s_IV="IV =0  有效 ";
    else
        l_s_IV="IV =1  无效 ";

    //        NT                     ：=BS1[7]<0..1>
    //                      <0>      ：=当前值
    //                      <1>       ：=非当前值
    int l_i_NT=(data_parse>>6)%2;
    QString l_s_NT;

    if(l_i_NT==0)
        l_s_NT="NT=0 当前值 ";
    else
        l_s_NT="NT=1 非当前值 ";

    //        SB                     ：=BS1[6]<0..1>
    //                      <0>      ：=未被取代
    //                      <1>      ：=被取代

    int l_i_SB=(data_parse>>5)%2;
    QString l_s_SB;

    if(l_i_SB==0)
        l_s_SB="SB=0 未被取代 ";
    else
        l_s_SB="SB=1 被取代 ";

    //        BL                     ：=BS1[5]<0..1>
    //                      <0>      ：=未被闭锁
    //                       <1>      ：=被闭锁

    int l_i_BL=(data_parse>>4)%2;
    QString l_s_BL;

    if(l_i_BL==0)
        l_s_BL="SB=0 未被闭锁  ";
    else
        l_s_BL="SB=1 被闭锁  ";

    //       EI                      ：=BS1[4]<0..1>                              (Type 6)
    //                      <0>       ：=动作时间有效
    //                      <1>       ：=动作时间无效

    int l_i_EI=(data_parse>>5)%2;
    QString l_s_EI;

    if(l_i_EI==0)
        l_s_EI="EI=0 动作时间有效  ";
    else
        l_s_EI="EI=1 动作时间无效  ";

    QString l_all="QDP=CP8{RES,EI,BL,SB,NT,IV}"+l_s_EI+l_s_BL+l_s_SB+l_s_NT+l_s_IV;
    qDebug()<<l_all;
    return l_all;
}


//********************************************************************************
//函数名：pParseVTI
//功能：带瞬变状态指示的值，用于变压器的步位置或者其他步位置信息(VTI)

QString MainWindow::pParseVTI(int data_parse)
{
//    VTI                     ：=CP8{Value,Transient}
//    Value=值                 ：=I7[1..7]<-64..+63>                         (Type 2.1)
//    Transient=瞬变状态        ：=BS1[8]<0..1>                             (Type 6)
//                  <0>	：=设备未在瞬变状态
//                  <1>        ：=设备处于瞬变状态

}


//********************************************************************************
//函数名：pParseBCR
//功能：二进制计数器读数(BCR)
QString MainWindow::pParseBCR(int data_parse)
{

}




